package cn.fuxi2022.gateway.filter;

import cn.fuxi2022.feign.api.GroupAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 网关全局过滤器
 * 验证当前请求是否合法
 * <p>
 * 该过滤器的优先级为最高（先通过该过滤器，在进行路由判断）
 * 注意：匹配到路由，该过滤器才会动作！！！
 */
@Component
public class AuthenticationFilter implements GlobalFilter, Ordered {


    private static final ThreadLocal<String> USERTHREADLOCAL = new ThreadLocal<>();

    @Autowired
    private GroupAuth groupAuth;

    /**
     * 处理当前请求，有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
     *
     * @param exchange 请求上下文，里面可以获取Request、Response等信息
     * @param chain    用来把请求委托给下一个过滤器
     * @return {@code Mono<Void>} 返回标示当前过滤器业务结束
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取当前 URI 和 token
        String path = exchange.getRequest().getURI().getPath();
        String token = exchange.getRequest().getHeaders().getFirst("token");

        // 2.服务调用鉴权模块获取返回值
        if (!groupAuth.checkUriAndToken(path, token)) {
            // 当前请求是非法的
            throw new RuntimeException("当前的请求路径或token错误，请检查是否正确");
        }

        // 写过滤器，第一行代码就是写放行请求，防止漏写
        return chain.filter(exchange);
    }

    /**
     * 设置当前优先级
     * 给过滤器设定优先级别的，值越大则优先级越低
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
